This is an R Markdown Notebook. Each section of the code is then explained.

First of all import the libraries needed

#install.packages(c("datavolley", "ovlytics"))
library(datavolley)
library(ggplot2)
library(dplyr)
library(ovlytics)

Import the file you are interested in

#filename <- "C:/Users/mirko/OneDrive - Politecnico di Milano/Altro/Volley/Conco2324/Parella Torino/Ritorno/&09_VOL-LIB_Libellula_b1fa_23_s.dvw"
d <- dir("C:/Users/mirko/OneDrive - Politecnico di Milano/Altro/Volley/Conco2324/Parella Torino/Ritorno/", pattern = "dvw$", full.names = TRUE)
lx <- list()
## read each file
for (fi in seq_along(d)) lx[[fi]] <- dv_read(d[fi], insert_technical_timeouts = FALSE)
## now extract the play-by-play component from each and bind them together
px <- list()
for (fi in seq_along(lx)) px[[fi]] <- plays(lx[[fi]])
#plays(lx[[1]])
px <- do.call(rbind, px)

Now let’s focus on attack rate. CHANGE THE ’‘’teamName’’’ variable according to the match you are interested in

attack_rate <- px %>% dplyr::filter(skill == "Attack", team == teamName) %>%
  group_by(team, start_zone) %>% dplyr::summarize(n_attacks = n()) %>%
  mutate(rate = n_attacks/sum(n_attacks)) %>% ungroup
`summarise()` has grouped output by 'team'. You can override using the `.groups` argument.
## add x, y coordinates associated with the zones
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$start_zone, end = "lower"))

## for team 2, these need to be on the top half of the diagram
tm2i <- attack_rate$team == teams(px)[2]
attack_rate[tm2i, c("x", "y")] <- dv_flip_xy(attack_rate[tm2i, c("x", "y")])

ggplot(attack_rate, aes(x, y, fill = rate)) + geom_tile() + ggcourt(labels = teams(px)) +
    scale_fill_gradient2(name = "Attack rate")

Now let’s plot the heatmap of where attacks ended

If you want a specific vector plot of attakcs directions:

playerName = 'ALESSIA DAMATO'
## first tabulate attacks by starting and ending zone
attack_rate <- px %>% dplyr::filter(team == teams(px)[2] & skill == "Attack" & team == teamName & player_name == playerName & start_zone == 4) %>%
  group_by(start_zone, end_zone) %>% tally() %>% ungroup

## convert counts to rates
attack_rate$rate <- attack_rate$n/sum(attack_rate$n)

## discard zones with zero attacks or missing location information
attack_rate <- attack_rate %>% dplyr::filter(rate>0 & !is.na(start_zone) & !is.na(end_zone))

## add starting x, y coordinates
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$start_zone, end = "lower", xynames = c("sx", "sy")))

## and ending x, y coordinates
attack_rate <- cbind(attack_rate, dv_xy(attack_rate$end_zone, end = "upper", xynames = c("ex", "ey")))

## plot in reverse order so largest arrows are on the bottom
attack_rate <- attack_rate %>% dplyr::arrange(desc(rate))

p <- ggplot(attack_rate, aes(x, y, col = rate)) + ggcourt(labels = c(teams(px)[2], ""), court_colour = "indoor")
for (n in 1:nrow(attack_rate))
    p <- p + geom_path(data = data.frame(x = c(attack_rate$sx[n], attack_rate$ex[n]),
                                         y = c(attack_rate$sy[n], attack_rate$ey[n]),
                                         rate = attack_rate$rate[n]),
                       aes(size = rate), lineend = "round",
                       arrow = arrow(length = unit(2, "mm"), type = "closed", angle = 20, ends = "last"))
p + scale_colour_gradient(name = "Attack rate") + guides(size = "none")

Reception plots

px %>% dplyr::filter(skill == "Reception", team == teamName, end_zone == 5) %>% group_by(player_name) %>% 
  dplyr::summarize(N_receptions = n(), error_rate = sum(evaluation_code == "=",na.rm = TRUE))

Sankey Diagram for Reception

This diagram is useful to detect the direction the other team suffers more.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

LS0tDQp0aXRsZTogIlZvbGxleWJhbGwgRGF0YSBBbmFseXNpcyINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBkZl9wcmludDogcGFnZWQNCiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gRWFjaCBzZWN0aW9uIG9mIHRoZSBjb2RlIGlzIHRoZW4gZXhwbGFpbmVkLg0KDQpGaXJzdCBvZiBhbGwgaW1wb3J0IHRoZSBsaWJyYXJpZXMgbmVlZGVkDQoNCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoYygiZGF0YXZvbGxleSIsICJvdmx5dGljcyIpKQ0KbGlicmFyeShkYXRhdm9sbGV5KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkob3ZseXRpY3MpDQpgYGANCg0KSW1wb3J0IHRoZSBmaWxlIHlvdSBhcmUgaW50ZXJlc3RlZCBpbg0KDQpgYGB7cn0NCiNmaWxlbmFtZSA8LSAiQzovVXNlcnMvbWlya28vT25lRHJpdmUgLSBQb2xpdGVjbmljbyBkaSBNaWxhbm8vQWx0cm8vVm9sbGV5L0NvbmNvMjMyNC9QYXJlbGxhIFRvcmluby9SaXRvcm5vLyYwOV9WT0wtTElCX0xpYmVsbHVsYV9iMWZhXzIzX3MuZHZ3Ig0KZCA8LSBkaXIoIkM6L1VzZXJzL21pcmtvL09uZURyaXZlIC0gUG9saXRlY25pY28gZGkgTWlsYW5vL0FsdHJvL1ZvbGxleS9Db25jbzIzMjQvUGFyZWxsYSBUb3Jpbm8vUml0b3Juby8iLCBwYXR0ZXJuID0gImR2dyQiLCBmdWxsLm5hbWVzID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCmx4IDwtIGxpc3QoKQ0KIyMgcmVhZCBlYWNoIGZpbGUNCmZvciAoZmkgaW4gc2VxX2Fsb25nKGQpKSBseFtbZmldXSA8LSBkdl9yZWFkKGRbZmldLCBpbnNlcnRfdGVjaG5pY2FsX3RpbWVvdXRzID0gRkFMU0UpDQojIyBub3cgZXh0cmFjdCB0aGUgcGxheS1ieS1wbGF5IGNvbXBvbmVudCBmcm9tIGVhY2ggYW5kIGJpbmQgdGhlbSB0b2dldGhlcg0KcHggPC0gbGlzdCgpDQpmb3IgKGZpIGluIHNlcV9hbG9uZyhseCkpIHB4W1tmaV1dIDwtIHBsYXlzKGx4W1tmaV1dKQ0KI3BsYXlzKGx4W1sxXV0pDQpweCA8LSBkby5jYWxsKHJiaW5kLCBweCkNCmBgYA0KDQpOb3cgbGV0J3MgZm9jdXMgb24gYXR0YWNrIHJhdGUuIENIQU5HRSBUSEUgJycndGVhbU5hbWUnJycgdmFyaWFibGUgYWNjb3JkaW5nIHRvIHRoZSBtYXRjaCB5b3UgYXJlIGludGVyZXN0ZWQgaW4NCg0KYGBge3J9DQp0ZWFtTmFtZSA9ICJWT0xMRVkgUEFSRUxMQSBUT1JJTk8iDQphdHRhY2tfcmF0ZSA8LSBweCAlPiUgZHBseXI6OmZpbHRlcihza2lsbCA9PSAiQXR0YWNrIiwgdGVhbSA9PSB0ZWFtTmFtZSkgJT4lDQogIGdyb3VwX2J5KHRlYW0sIHN0YXJ0X3pvbmUpICU+JSBkcGx5cjo6c3VtbWFyaXplKG5fYXR0YWNrcyA9IG4oKSkgJT4lDQogIG11dGF0ZShyYXRlID0gbl9hdHRhY2tzL3N1bShuX2F0dGFja3MpKSAlPiUgdW5ncm91cA0KYGBgDQoNCmBgYHtyfQ0KIyMgYWRkIHgsIHkgY29vcmRpbmF0ZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB6b25lcw0KYXR0YWNrX3JhdGUgPC0gY2JpbmQoYXR0YWNrX3JhdGUsIGR2X3h5KGF0dGFja19yYXRlJHN0YXJ0X3pvbmUsIGVuZCA9ICJsb3dlciIpKQ0KDQojIyBmb3IgdGVhbSAyLCB0aGVzZSBuZWVkIHRvIGJlIG9uIHRoZSB0b3AgaGFsZiBvZiB0aGUgZGlhZ3JhbQ0KdG0yaSA8LSBhdHRhY2tfcmF0ZSR0ZWFtID09IHRlYW1zKHB4KVsyXQ0KYXR0YWNrX3JhdGVbdG0yaSwgYygieCIsICJ5IildIDwtIGR2X2ZsaXBfeHkoYXR0YWNrX3JhdGVbdG0yaSwgYygieCIsICJ5IildKQ0KDQpnZ3Bsb3QoYXR0YWNrX3JhdGUsIGFlcyh4LCB5LCBmaWxsID0gcmF0ZSkpICsgZ2VvbV90aWxlKCkgKyBnZ2NvdXJ0KGxhYmVscyA9IHRlYW1zKHB4KSkgKw0KICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG5hbWUgPSAiQXR0YWNrIHJhdGUiKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGF0dGFja19yYXRlLCBhZXMoeCwgeSwgZmlsbCA9IHJhdGUpKSArDQogICAgIyMgcGxvdCBqdXN0IHRoZSBiYWNrZ3JvdW5kIGNvdXJ0IGNvbG91cg0KICAgIGdnY291cnQoY291cnRfY29sb3VyID0gImluZG9vciIsIGJhY2tncm91bmRfb25seSA9IFRSVUUpICsNCiAgICAjIyBhZGQgdGhlIGhlYXRtYXANCiAgICBnZW9tX3RpbGUoKSArDQogICAgIyMgbm93IGFkZCB0aGUgZ3JpZCBsaW5lcyBhbmQgbGFiZWxzDQogICAgZ2djb3VydChsYWJlbHMgPSB0ZWFtcyhweCksIGNvdXJ0X2NvbG91ciA9ICJpbmRvb3IiLCBmb3JlZ3JvdW5kX29ubHkgPSBUUlVFKSArDQogICAgc2NhbGVfZmlsbF9ncmFkaWVudDIobmFtZSA9ICJBdHRhY2sgcmF0ZSIpDQpgYGANCg0KTm93IGxldCdzIHBsb3QgdGhlIGhlYXRtYXAgb2Ygd2hlcmUgYXR0YWNrcyBlbmRlZA0KDQpgYGB7cn0NCnBsYXllck5hbWUgPSAiQUxFU1NJQSBEQU1BVE8iDQojIyBjYWxjdWxhdGUgYXR0YWNrIGZyZXF1ZW5jeSBieSB6b25lLCBwZXIgdGVhbQ0KYXR0YWNrX3JhdGUgPC0gcHggJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIodGVhbSA9PSB0ZWFtTmFtZSAmIHNraWxsID09ICJBdHRhY2siICYgcGxheWVyX25hbWUgPT0gcGxheWVyTmFtZSAmIHN0YXJ0X3pvbmUgPT0gNCkgJT4lDQogICAgZ3JvdXBfYnkoZW5kX3pvbmUpICU+JSBkcGx5cjo6c3VtbWFyaXplKG5fYXR0YWNrcyA9IG4oKSkgJT4lDQogICAgbXV0YXRlKHJhdGUgPSBuX2F0dGFja3Mvc3VtKG5fYXR0YWNrcykpICU+JSB1bmdyb3VwDQphdHRhY2tfcmF0ZSA8LSBjYmluZChhdHRhY2tfcmF0ZSwgZHZfeHkoYXR0YWNrX3JhdGUkZW5kX3pvbmUsIGVuZCA9ICJsb3dlciIpKQ0KZ2dwbG90KGF0dGFja19yYXRlLCBhZXMoeCwgeSwgZmlsbCA9IG5fYXR0YWNrcykpICsgZ2VvbV90aWxlKCkgKyBnZ2NvdXJ0KCJsb3dlciIsIGxhYmVscyA9IE5VTEwpICsNCiAgICBzY2FsZV9maWxsX2dyYWRpZW50MihuYW1lID0gIlJhdGU6IGF0dGFja1xuZW5kIGxvY2F0aW9uIikgKyBnZW9tX3RleHQoYWVzKGxhYmVsID0gbl9hdHRhY2tzKSwgY29sb3IgPSAiYmxhY2siKQ0KYGBgDQoNCmBgYHtyfQ0KYXR0YWNrX3JhdGUgPC0gcHggJT4lIA0KICAgIGRwbHlyOjpmaWx0ZXIodGVhbSAhPSB0ZWFtTmFtZSAmIHNraWxsID09ICJBdHRhY2siICYgc3RhcnRfem9uZSA9PSA0ICYgIWlzLm5hKGVuZF9zdWJ6b25lKSkgJT4lDQogICAgZ3JvdXBfYnkoZW5kX3pvbmUsIGVuZF9zdWJ6b25lKSAlPiUgZHBseXI6OnN1bW1hcml6ZShuX2F0dGFja3MgPSBuKCkpICU+JQ0KICAgIG11dGF0ZShyYXRlID0gbl9hdHRhY2tzL3N1bShuX2F0dGFja3MpKSAlPiUgdW5ncm91cA0KYGBgDQoNCklmIHlvdSB3YW50IGEgc3BlY2lmaWMgdmVjdG9yIHBsb3Qgb2YgYXR0YWtjcyBkaXJlY3Rpb25zOg0KDQpgYGB7cn0NCnBsYXllck5hbWUgPSAnQUxFU1NJQSBEQU1BVE8nDQojIyBmaXJzdCB0YWJ1bGF0ZSBhdHRhY2tzIGJ5IHN0YXJ0aW5nIGFuZCBlbmRpbmcgem9uZQ0KYXR0YWNrX3JhdGUgPC0gcHggJT4lIGRwbHlyOjpmaWx0ZXIodGVhbSA9PSB0ZWFtcyhweClbMl0gJiBza2lsbCA9PSAiQXR0YWNrIiAmIHRlYW0gPT0gdGVhbU5hbWUgJiBwbGF5ZXJfbmFtZSA9PSBwbGF5ZXJOYW1lICYgc3RhcnRfem9uZSA9PSA0KSAlPiUNCiAgZ3JvdXBfYnkoc3RhcnRfem9uZSwgZW5kX3pvbmUpICU+JSB0YWxseSgpICU+JSB1bmdyb3VwDQoNCiMjIGNvbnZlcnQgY291bnRzIHRvIHJhdGVzDQphdHRhY2tfcmF0ZSRyYXRlIDwtIGF0dGFja19yYXRlJG4vc3VtKGF0dGFja19yYXRlJG4pDQoNCiMjIGRpc2NhcmQgem9uZXMgd2l0aCB6ZXJvIGF0dGFja3Mgb3IgbWlzc2luZyBsb2NhdGlvbiBpbmZvcm1hdGlvbg0KYXR0YWNrX3JhdGUgPC0gYXR0YWNrX3JhdGUgJT4lIGRwbHlyOjpmaWx0ZXIocmF0ZT4wICYgIWlzLm5hKHN0YXJ0X3pvbmUpICYgIWlzLm5hKGVuZF96b25lKSkNCg0KIyMgYWRkIHN0YXJ0aW5nIHgsIHkgY29vcmRpbmF0ZXMNCmF0dGFja19yYXRlIDwtIGNiaW5kKGF0dGFja19yYXRlLCBkdl94eShhdHRhY2tfcmF0ZSRzdGFydF96b25lLCBlbmQgPSAibG93ZXIiLCB4eW5hbWVzID0gYygic3giLCAic3kiKSkpDQoNCiMjIGFuZCBlbmRpbmcgeCwgeSBjb29yZGluYXRlcw0KYXR0YWNrX3JhdGUgPC0gY2JpbmQoYXR0YWNrX3JhdGUsIGR2X3h5KGF0dGFja19yYXRlJGVuZF96b25lLCBlbmQgPSAidXBwZXIiLCB4eW5hbWVzID0gYygiZXgiLCAiZXkiKSkpDQoNCiMjIHBsb3QgaW4gcmV2ZXJzZSBvcmRlciBzbyBsYXJnZXN0IGFycm93cyBhcmUgb24gdGhlIGJvdHRvbQ0KYXR0YWNrX3JhdGUgPC0gYXR0YWNrX3JhdGUgJT4lIGRwbHlyOjphcnJhbmdlKGRlc2MocmF0ZSkpDQoNCnAgPC0gZ2dwbG90KGF0dGFja19yYXRlLCBhZXMoeCwgeSwgY29sID0gcmF0ZSkpICsgZ2djb3VydChsYWJlbHMgPSBjKHRlYW1zKHB4KVsyXSwgIiIpLCBjb3VydF9jb2xvdXIgPSAiaW5kb29yIikNCmZvciAobiBpbiAxOm5yb3coYXR0YWNrX3JhdGUpKQ0KICAgIHAgPC0gcCArIGdlb21fcGF0aChkYXRhID0gZGF0YS5mcmFtZSh4ID0gYyhhdHRhY2tfcmF0ZSRzeFtuXSwgYXR0YWNrX3JhdGUkZXhbbl0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gYyhhdHRhY2tfcmF0ZSRzeVtuXSwgYXR0YWNrX3JhdGUkZXlbbl0pLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXRlID0gYXR0YWNrX3JhdGUkcmF0ZVtuXSksDQogICAgICAgICAgICAgICAgICAgICAgIGFlcyhzaXplID0gcmF0ZSksIGxpbmVlbmQgPSAicm91bmQiLA0KICAgICAgICAgICAgICAgICAgICAgICBhcnJvdyA9IGFycm93KGxlbmd0aCA9IHVuaXQoMiwgIm1tIiksIHR5cGUgPSAiY2xvc2VkIiwgYW5nbGUgPSAyMCwgZW5kcyA9ICJsYXN0IikpDQpwICsgc2NhbGVfY29sb3VyX2dyYWRpZW50KG5hbWUgPSAiQXR0YWNrIHJhdGUiKSArIGd1aWRlcyhzaXplID0gIm5vbmUiKQ0KYGBgDQoNCiMjIFJlY2VwdGlvbiBwbG90cw0KDQpgYGB7cn0NCnB4ICU+JSBkcGx5cjo6ZmlsdGVyKHNraWxsID09ICJSZWNlcHRpb24iLCB0ZWFtID09IHRlYW1OYW1lLCBlbmRfem9uZSA9PSA1KSAlPiUgZ3JvdXBfYnkocGxheWVyX25hbWUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZShOX3JlY2VwdGlvbnMgPSBuKCksIGVycm9yX3JhdGUgPSBzdW0oZXZhbHVhdGlvbl9jb2RlID09ICI9IixuYS5ybSA9IFRSVUUpKQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGVfZGF0YSA8LSBweCAlPiUgDQogIGRwbHlyOjpmaWx0ZXIoc2tpbGwgPT0gIlJlY2VwdGlvbiIsIHRlYW0gPT0gdGVhbU5hbWUsIGVuZF96b25lID09IDUpICU+JSANCiAgZ3JvdXBfYnkocGxheWVyX25hbWUpICU+JSANCiAgZHBseXI6OnN1bW1hcml6ZSgNCiAgICBOX3JlY2VwdGlvbnMgPSBuKCksDQogICAgY291bnRfcGVyZmV0dGUgPSBzdW0oZXZhbHVhdGlvbl9jb2RlID09ICIjIiwgbmEucm0gPSBUUlVFKSwNCiAgICBjb3VudF9wb3NpdGl2ZSA9IHN1bShldmFsdWF0aW9uX2NvZGUgPT0gIisiLCBuYS5ybSA9IFRSVUUpLA0KICAgIGNvdW50X2VzY2FsYW1hdGl2ZSA9IHN1bShldmFsdWF0aW9uX2NvZGUgPT0gIiEiLCBuYS5ybSA9IFRSVUUpLA0KICAgIGNvdW50X25lZ2F0aXZlID0gc3VtKGV2YWx1YXRpb25fY29kZSA9PSAiLSIsIG5hLnJtID0gVFJVRSksDQogICAgY291bnRfZXJyb3JpID0gc3VtKGV2YWx1YXRpb25fY29kZSA9PSAiPSIsIG5hLnJtID0gVFJVRSksDQogICAgcG9zaXRpdml0w6AgPSAoY291bnRfcG9zaXRpdmUgKyBjb3VudF9wZXJmZXR0ZSkvTl9yZWNlcHRpb25zLA0KICAgIGVmZmljaWVuemEgPSAoY291bnRfcG9zaXRpdmUgKyBjb3VudF9wZXJmZXR0ZSAtIGNvdW50X2Vycm9yaSkvTl9yZWNlcHRpb25zLA0KICApDQoNCnRhYmxlX2RhdGENCmBgYA0KDQpgYGB7cn0NCiMgSGlzdG9ncmFtIG9mIHBvc2l0aXZpdMOgDQpnZ3Bsb3QodGFibGVfZGF0YSwgYWVzKHggPSBwbGF5ZXJfbmFtZSwgeSA9IHBvc2l0aXZpdMOgKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJibHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQmFyIFBsb3Qgb2YgUG9zaXRpdml0w6AiLA0KICAgICAgIHggPSAiR2lvY2F0b3JpIiwNCiAgICAgICB5ID0gIlBvc2l0aXZpdMOgIikNCg0KZ2dwbG90KHRhYmxlX2RhdGEsIGFlcyh4ID0gcGxheWVyX25hbWUsIHkgPSBlZmZpY2llbnphKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJibHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiRWZmaWNpZW56YSIsDQogICAgICAgeCA9ICJHaW9jYXRvcmkiLA0KICAgICAgIHkgPSAiRWZmaWNpZW56YSIpDQpgYGANCg0KYGBge3J9DQoNCnJlY2VwdGlvbl9yYXRlIDwtIHB4ICU+JSBkcGx5cjo6ZmlsdGVyKHNraWxsID09ICJSZWNlcHRpb24iLCB0ZWFtPT10ZWFtTmFtZSkgJT4lDQogICAgZ3JvdXBfYnkocGxheWVyX25hbWUsIGVuZF96b25lLCBldmFsdWF0aW9uX2NvZGUpICU+JSBkcGx5cjo6c3VtbWFyaXplKG5fcmVjZXB0aW9uID0gbigpKSAlPiUNCiAgICBtdXRhdGUocmF0ZSA9IChldmFsdWF0aW9uX2NvZGUgPT0gIj0iKS9zdW0obl9yZWNlcHRpb24pKSAlPiUgdW5ncm91cA0KDQojIyBhZGQgeCwgeSBjb29yZGluYXRlcyBhc3NvY2lhdGVkIHdpdGggdGhlIHpvbmVzDQpyZWNlcHRpb25fcmF0ZSA8LSBjYmluZChyZWNlcHRpb25fcmF0ZSwgZHZfeHkocmVjZXB0aW9uX3JhdGUkZW5kX3pvbmUsIGVuZCA9ICJsb3dlciIpKQ0KDQojIyBmb3IgdGVhbSAyLCB0aGVzZSBuZWVkIHRvIGJlIG9uIHRoZSB0b3AgaGFsZiBvZiB0aGUgZGlhZ3JhbQ0KdG0yaSA8LSByZWNlcHRpb25fcmF0ZSR0ZWFtID09IHRlYW1zKHB4KVsyXQ0KcmVjZXB0aW9uX3JhdGVbdG0yaSwgYygieCIsICJ5IildIDwtIGR2X2ZsaXBfeHkocmVjZXB0aW9uX3JhdGVbdG0yaSwgYygieCIsICJ5IildKQ0KDQpnZ3Bsb3QocmVjZXB0aW9uX3JhdGUsIGFlcyh4LCB5LCBmaWxsID0gcmF0ZSkpICsgZ2VvbV90aWxlKCkgKyBnZ2NvdXJ0KGxhYmVscyA9IHRlYW1zKHB4KSkgKw0KICAgIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKG5hbWUgPSAiUmVjZXB0aW9uIHJhdGUiKQ0KDQojIEZpbmQgdGhlIHBsYXllciB3aXRoIHRoZSBtYXhpbXVtIHJhdGUgZm9yIGVhY2ggem9uZQ0KbWF4X3JhdGVfcGxheWVycyA8LSByZWNlcHRpb25fcmF0ZSAlPiUNCiAgZ3JvdXBfYnkoZW5kX3pvbmUpICU+JQ0KICBzbGljZSh3aGljaC5tYXgocmF0ZSkpDQoNCiMgUGxvdCB0aGUgaGVhdG1hcCB3aXRoIG9ubHkgdGhlIHBsYXllciB3aXRoIG1heCByYXRlIGZvciBlYWNoIHpvbmUNCmdncGxvdChyZWNlcHRpb25fcmF0ZSwgYWVzKHgsIHksIGZpbGwgPSByYXRlKSkgKw0KICBnZW9tX3RpbGUoKSArDQogIGdlb21fdGV4dChkYXRhID0gbWF4X3JhdGVfcGxheWVyc1ttYXhfcmF0ZV9wbGF5ZXJzJHJhdGUgPiAwLCBdLCBhZXMobGFiZWwgPSBwYXN0ZShwbGF5ZXJfbmFtZSwgIjpcbiIsIHJvdW5kKHJhdGUgKiAxMDApLCAiJSIpKSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMykgKw0KICBnZ2NvdXJ0KGxhYmVscyA9IHRlYW1zKHB4KSkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50MihuYW1lID0gIlJlY2VwdGlvbiByYXRlIikNCmBgYA0KDQojIyBTYW5rZXkgRGlhZ3JhbSBmb3IgUmVjZXB0aW9uDQoNClRoaXMgZGlhZ3JhbSBpcyB1c2VmdWwgdG8gZGV0ZWN0IHRoZSBkaXJlY3Rpb24gdGhlIG90aGVyIHRlYW0gc3VmZmVycyBtb3JlLg0KDQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJuZXR3b3JrRDMiKQ0KI2xpYnJhcnkocGxvdGx5KQ0KDQojIEV4YW1wbGUgZGF0YQ0KIyBBc3N1bWluZyB5b3UgYWxyZWFkeSBoYXZlIGEgZGF0YWZyYW1lIGNhbGxlZCAncmVjZXB0aW9uX2RhdGEnIHdpdGggY29sdW1ucyAnc3RhcnRfem9uZScsICdlbmRfem9uZScsIGFuZCAnZXZhbHVhdGlvbl9jb2RlJw0KDQojIFByZXBhcmUgZGF0YTogY2FsY3VsYXRlIGNvdW50IG9mIGV2YWx1YXRpb25fY29kZSBmb3IgZWFjaCBjb21iaW5hdGlvbiBvZiBzdGFydF96b25lIGFuZCBlbmRfem9uZQ0Kc2Fua2V5X2RhdGEgPC0gcHggJT4lDQogIGZpbHRlcighaXMubmEoc3RhcnRfem9uZSkgJiAhaXMubmEoZW5kX3pvbmUpICYgc2tpbGwgPT0gIlJlY2VwdGlvbiIgJiAoZXZhbHVhdGlvbl9jb2RlID09ICc9J3xldmFsdWF0aW9uX2NvZGUgPT0gJy0nKSkgJT4lDQogIGdyb3VwX2J5KHN0YXJ0X3pvbmUsIGVuZF96b25lLCBldmFsdWF0aW9uX2NvZGUpICU+JQ0KICBzdW1tYXJpemUoY291bnQgPSBuKCkpICU+JQ0KICBncm91cF9ieShzdGFydF96b25lLCBlbmRfem9uZSkgJT4lDQogIHN1bW1hcml6ZSh2YWx1ZSA9IHN1bShjb3VudCkpDQoNCiMgQ3JlYXRlIFNhbmtleSBkaWFncmFtDQpwbG90X2x5KA0KICB0eXBlID0gInNhbmtleSIsDQogIG9yaWVudGF0aW9uID0gImgiLA0KICBub2RlID0gbGlzdCgNCiAgICBsYWJlbCA9IHVuaXF1ZShjKHNhbmtleV9kYXRhJHN0YXJ0X3pvbmUsIHNhbmtleV9kYXRhJGVuZF96b25lKSkNCiAgKSwNCiAgbGluayA9IGxpc3QoDQogICAgc291cmNlID0gbWF0Y2goc2Fua2V5X2RhdGEkc3RhcnRfem9uZSwgdW5pcXVlKGMoc2Fua2V5X2RhdGEkc3RhcnRfem9uZSwgc2Fua2V5X2RhdGEkZW5kX3pvbmUpKSkgLSAxLA0KICAgIHRhcmdldCA9IG1hdGNoKHNhbmtleV9kYXRhJGVuZF96b25lLCB1bmlxdWUoYyhzYW5rZXlfZGF0YSRzdGFydF96b25lLCBzYW5rZXlfZGF0YSRlbmRfem9uZSkpKSAtIDEsDQogICAgdmFsdWUgPSBzYW5rZXlfZGF0YSR2YWx1ZQ0KICApDQopDQoNCg0KYGBgDQoNCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4NCg==